package health.lm.com.component_base.widget;

import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.URI;
import java.net.URL;

/**
 * Created by Android Studio .
 * 作者：zhong
 * 日期：2018/12/6
 * 邮箱：15206394364@163.com
 * 介绍：获取html中的图片，重写获取方式TextView 显示富文本（包含图片），能够正确显示图片
 * 修订：====================
 */
public class ZImageGetter implements Html.ImageGetter {
    private static int urlNum = 0;
    TextView container;
    URI baseUri;
    private boolean matchParentWidth;

    public ZImageGetter(TextView container) {
        this.container = container;
        this.matchParentWidth = false;
    }

    public ZImageGetter(TextView container, String baseUrl) {
        this.container = container;
        if (baseUrl != null) {
            this.baseUri = URI.create(baseUrl);
        }
    }

    public ZImageGetter(TextView container, String baseUrl, boolean matchParentWidth) {
        urlNum = 0;
        this.container = container;
        this.matchParentWidth = matchParentWidth;
        if (baseUrl != null) {
            this.baseUri = URI.create(baseUrl);
        }

    }

    @Override
    public Drawable getDrawable(String s) {
        Log.e("urls", s);
        ImageGetterAsyncTask.UrlDrawable urlDrawable = new ImageGetterAsyncTask.UrlDrawable();
        urlNum++;//限制详情页最多显示20张图片
        if (urlNum < 20) {
            // get the actual source
            ImageGetterAsyncTask asyncTask = new ImageGetterAsyncTask(urlDrawable, this, container, matchParentWidth);
            Log.e("urls", s);
            asyncTask.execute(s);
        }
        // return reference to URLDrawable which will asynchronously load the image specified in the src tag
        return urlDrawable;
    }

    private static class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> {
        private final WeakReference<UrlDrawable> drawableReference;
        private final WeakReference<ZImageGetter> imageGetterReference;
        private final WeakReference<View> containerReference;
        private String source;
        private boolean matchParentWidth;
        private float scale;

        ImageGetterAsyncTask(UrlDrawable drawableReference, ZImageGetter imageGetterReference
                , View containerReference, boolean matchParentWidth) {
            this.drawableReference = new WeakReference<>(drawableReference);
            this.imageGetterReference = new WeakReference<>(imageGetterReference);
            this.containerReference = new WeakReference<>(containerReference);
            this.matchParentWidth = matchParentWidth;
        }

        @Override
        protected Drawable doInBackground(String... strings) {
            source = strings[0];
            Log.e("doInBackground", source);
            return fetchDrawable(source);
        }

        @Override
        protected void onPostExecute(Drawable drawable) {
            if (drawable == null) {
                return;
            }
            final UrlDrawable urlDrawable = drawableReference.get();
            if (urlDrawable == null) {
                return;
            }
            // set the correct bound according to the result from HTTP call
            urlDrawable.setBounds(0, 0, (int) (drawable.getIntrinsicWidth() * scale)
                    , (int) (drawable.getIntrinsicHeight() * scale));
            // change the reference of the current drawable to the result from the HTTP call
            urlDrawable.drawable = drawable;
            final ZImageGetter imageGetter = imageGetterReference.get();
            if (imageGetter == null) {
                return;
            }

            // redraw the image by invalidating the container
            imageGetter.container.invalidate();
            // re-set text to fix images overlapping text
            imageGetter.container.setText(imageGetter.container.getText());
        }

        /**
         * Get the Drawable from URL
         */
        private Drawable fetchDrawable(String urlString) {
            try {
                InputStream is = fetch(urlString);
                Drawable drawable = Drawable.createFromStream(is, "src");
                scale = getScale(drawable);
                drawable.setBounds(0, 0, (int) (drawable.getIntrinsicWidth() * scale), (int) (drawable.getIntrinsicHeight() * scale));
                return drawable;
            } catch (Exception e) {
                return null;
            }
        }

        private float getScale(Drawable drawable) {
            View container = containerReference.get();
            if (!matchParentWidth || container == null) {
                return 1f;
            }
            float maxWidth = container.getWidth();
            float originalDrawableWidth = drawable.getIntrinsicWidth();
            return maxWidth / originalDrawableWidth;
        }

        private InputStream fetch(String urlString) throws IOException {
            URL url;
            final ZImageGetter imageGetter = imageGetterReference.get();
            if (imageGetter == null) {
                return null;
            }
            if (imageGetter.baseUri != null) {
                url = imageGetter.baseUri.resolve(urlString).toURL();
            } else {
                url = URI.create(urlString).toURL();
            }

            return (InputStream) url.getContent();
        }

        @SuppressWarnings("deprecation")
        public static class UrlDrawable extends BitmapDrawable {
            protected Drawable drawable;

            @Override
            public void draw(Canvas canvas) {
                // override the draw to facilitate refresh function later
                if (drawable != null) {
                    drawable.draw(canvas);
                }
            }
        }
    }
}
